package nancal.mp.service.jenkins

import nancal.mp.db.mongo.entity.dev.AppDeploySetting
import nancal.mp.db.mongo.entity.dev.JenkinsLog
import nancal.mp.db.mongo.extend.getAppDeploySetting
import nancal.mp.db.mongo.mor
import nbcp.base.extend.AsString
import nbcp.base.extend.HasValue
import nbcp.base.extend.must
import nbcp.base.utils.ResourceUtil
import nbcp.base.utils.UrlUtil
import org.apache.commons.text.StringEscapeUtils

class JenkinsCmdStyleScript(val task: JenkinsLog = JenkinsLog()) : JenkinsScript {
    val appDeploySetting: AppDeploySetting
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(task.buildInfo.targetEnv)
        }


    val template by lazy {
        return@lazy ResourceUtil.readResourceContentText("devops/jenkins/cmd-template.xml")
                .must { it.HasValue }
                .elseThrow { "找不到 devops/jenkins/cmd-template.xml 资源" }
    }

    /**
     * 转义字符列表： https://html.spec.whatwg.org/entities.json
     */
    fun getStepTemplate(value: String): String {
        return """
<hudson.tasks.Shell>
    <command>bash -c '''#!/bin/bash
${StringEscapeUtils.escapeXml11(value)}
'''</command>
    <configuredLocalRules/>
</hudson.tasks.Shell>
"""
    }

    private fun getStartStage(): String {
        var dockerLoginScript =  ""

        if(appDeploySetting.harborServer.host.HasValue && appDeploySetting.harborServer.userName.HasValue ){
            dockerLoginScript = """
    echo "登录到 harbor: ${appDeploySetting.harborServer.host}"
    echo "${this.appDeploySetting.sudo} docker login -u ${appDeploySetting.harborServer.userName} -p xxx ${appDeploySetting.harborServer.host}"
    ${this.appDeploySetting.sudo} docker login -u ${appDeploySetting.harborServer.userName} -p ${appDeploySetting.harborServer.password} ${appDeploySetting.harborServer.host}
"""
        }

        return getStepTemplate(
                """
${dockerLoginScript}

echo "[[${this.task.buildInfo.appCnName.AsString(this.task.buildInfo.appName)}]]"
${this.appDeploySetting.sudo} rm -rf *
${this.appDeploySetting.sudo} chmod a+rw ./ -R
echo `date "+%Y-%m-%d %H:%M:%S"`"下载指令..."
echo "﹍﹎﹍﹎﹍﹎﹎﹎"

function getPwdInDockerPath2(){
    path=${'$'}1
    if [ "${'$'}path" == "" ]; then
        path=`pwd`
    fi
    
    if [ "${appDeploySetting.jenkinsServer.jenkinsHomePathMountToDocker}" == "" ]; then
        echo ${'$'}path
        return ;
    fi
    
    #实际 =  挂载的外部目录 +  当前目录去除 /var/jenkins_home 部分
    echo ${appDeploySetting.jenkinsServer.jenkinsHomePathMountToDocker}${'$'}{path:17}
}

${this.appDeploySetting.sudo} docker run --rm --privileged=true ${appDeploySetting.dockerBuildAddHostsParameters} \
   -v `getPwdInDockerPath2`:`pwd`  -w `pwd` \
   ${appDeploySetting.getOpsBaseBashImage()} \
   bash -c "set -x ; wget -q ${appDeploySetting.mpIntegrationApiUrl}/ops/jenkins/cmd/file/${task.id}?admin-token=${UrlUtil.encodeURIComponent(appDeploySetting.adminToken)} -O ops-cmd.zip && unzip -q -o -d ./ ops-cmd.zip && dos2unix *.sh 2>/dev/null && pwd && tree -L 3 ./"
echo "﹊﹉﹊﹉﹊﹉﹊﹊"

"""
        )
    }


    override fun genStage(name: String, content: String): String {
        return getStepTemplate(
                """
echo [[$name]]
echo "source main.sh " &&  source main.sh

${content}

"""
        )
    }



    /**
     * lib流水线
     */
    override fun getLibJenkinsPipeLine(): String {
        if (appDeploySetting.mpIntegrationApiUrl.isNullOrEmpty()) {
            throw RuntimeException("${appDeploySetting.code} appDeploySetting.mpIntegrationApiHost 不能为空")
        }
        if (appDeploySetting.nexusServer.nexusHttpUrl.isNullOrEmpty()) {
            throw RuntimeException("${appDeploySetting.code} appDeploySetting.nexusServer.hostUrl 不能为空")
        }

        var content = """
${getStartStage()}
${getCodeStage()}
${getCompileStage()}
${genStage("完成", """echo 完成 """)} 
"""

        return template
                .replace("@shells@", content)
                .replace("@description@", this.task.buildInfo.serviceName)
    }

    override fun getNativeJenkinsPipeLine(): String {
        if (appDeploySetting.mpIntegrationApiUrl.isNullOrEmpty()) {
            throw RuntimeException("${appDeploySetting.code} appDeploySetting.mpIntegrationApiHost 不能为空")
        }

        var gitBuildInfo = task.buildInfo;

        var content = """
${getStartStage()}
${getCodeStage()}
${getCompileStage()}
${getPushState(appDeploySetting.harborServer.host.HasValue)}
${unzipDockerTar(appDeploySetting.harborServer.host.HasValue)}
${
            genStage(
                    "归档", """
${this.appDeploySetting.sudo} bash sys-pre-deploy.sh 
${this.appDeploySetting.sudo} bash sys-post-deploy.sh
"""
            )
        }

"""

        return template
                .replace("@shells@", content)
                .replace("@description@", this.task.buildInfo.serviceName)
    }


    override fun getDockerJenkinsPipeLine(): String {
        if (appDeploySetting.mpIntegrationApiUrl.isNullOrEmpty()) {
            throw RuntimeException("${appDeploySetting.code} appDeploySetting.mpIntegrationApiHost 不能为空")
        }

        var content = """
${getStartStage()}
${getCodeStage()}
${getCompileStage()}
${getPushState(appDeploySetting.harborServer.host.HasValue)}
${unzipDockerTar(appDeploySetting.harborServer.host.HasValue)}
${
            genStage(
                    "检查启动", """
${this.appDeploySetting.sudo} bash sys-pre-deploy.sh
check-docker-status
${this.appDeploySetting.sudo} bash sys-post-deploy.sh
"""
            )
        }

"""

        return template
                .replace("@shells@", content)
                .replace("@description@", this.task.buildInfo.serviceName)
    }


    override fun getK8sJenkinsPipeLine(): String {
        if (appDeploySetting.mpIntegrationApiUrl.isNullOrEmpty()) {
            throw RuntimeException("${appDeploySetting.code} appDeploySetting.mpIntegrationApiHost 不能为空")
        }
//        if (appDeploySetting.harborServer.host.isNullOrEmpty()) {
//            throw RuntimeException("${appDeploySetting.code} appDeploySetting.harborHost 不能为空")
//        }

        var content = """
${getStartStage()}
${getCodeStage()}
${getCompileStage()}
${getPushState(appDeploySetting.harborServer.host.HasValue)}
${
            genStage(
                    "部署到K8s", """
${this.appDeploySetting.sudo} bash sys-pre-deploy.sh

run-in-docker deploy-k8s
run-in-docker update-nginx-conf

${this.appDeploySetting.sudo} bash sys-post-deploy.sh
"""
            )
        }
${
            genStage(
                    "检查启动", """
run-in-docker check-k8s-status
echo ""
"""
            )
        } 
"""

        return template
                .replace("@shells@", content)
                .replace("@description@", this.task.buildInfo.serviceName)

    }
}